package com.yonyou.crm.sprc.oppflow.service;

import com.yonyou.crm.base.doc.service.BaseDocDetailBizServiceImpl;
import com.yonyou.crm.common.biz.service.BaseBizServiceImpl;
import com.yonyou.crm.common.enumeration.service.EnumBizServiceImpl;
import com.yonyou.crm.common.field.handler.FieldRelationHandler;
import com.yonyou.crm.common.field.relation.EnumFieldRelation;
import com.yonyou.crm.common.field.relation.FieldRelation;
import com.yonyou.crm.common.field.relation.RefFieldRelation;
import com.yonyou.crm.common.page.entity.Page;
import com.yonyou.crm.sprc.oppaction.entity.OppactionVO;
import com.yonyou.crm.sprc.oppaction.service.OppactionBizServiceImpl;
import com.yonyou.crm.sprc.oppdimension.entity.OppdimensionVO;
import com.yonyou.crm.sprc.oppdimension.service.OppdimensionBizServiceImpl;
import com.yonyou.crm.sprc.oppflow.entity.OppflowVO;
import com.yonyou.crm.sprc.oppstage.entity.OppstageVO;
import com.yonyou.crm.sprc.oppstage.service.OppstageBizServiceImpl;
import com.yonyou.crm.sys.modules.service.BiztypeBizServiceImpl;
import com.yonyou.iuap.context.InvocationInfoProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class OppflowBizServiceImpl extends BaseBizServiceImpl<OppflowVO> {

    @Autowired
    private EnumBizServiceImpl enumService;
    @Autowired
    private OppstageBizServiceImpl stageService;
    @Autowired
    private OppdimensionBizServiceImpl dimService;
    @Autowired
    private OppactionBizServiceImpl actionService;
    @Autowired
    private BaseDocDetailBizServiceImpl baseDocDetailBizService;
    @Autowired
    private BiztypeBizServiceImpl biztypeService;

    public List<OppflowVO> getOppflowList(Map<String, Object> paraMap) {

        List<OppflowVO> voList = dao.selectVoList(OppflowVO.class, "listOppflow", paraMap);

        trans(voList);

        return voList;
    }

    public Page<OppflowVO> getList(Page<OppflowVO> page, Map<String, Object> paramMap) {
        {
            Page<OppflowVO> oppflowPage = null;
            if (paramMap != null) {
                oppflowPage = super.pageSelect(OppflowVO.class, page, paramMap.keySet().toArray(new String[0]), paramMap.values().toArray(new Object[0]));
            } else {
                oppflowPage = super.pageSelect(OppflowVO.class, page, null, null);
            }

            trans(oppflowPage.getData());

            return oppflowPage;
        }
    }

    @Override
    protected void beforeSaveVO(OppflowVO vo) {

        super.beforeSaveVO(vo);
        vo.setTenantId(new Long(InvocationInfoProxy.getTenantid()));

        vo.setIsPreseted(new Integer("2"));//非预置

    }

    public OppflowVO saveVO(OppflowVO vo, List<Map<String, Object>> flowStageList, List<Map<String, Object>> stageActionList) {

        vo = super.saveVO(vo);
        Long flow_id = vo.getId();
        //待流程插入完成后，向List中的每条数据中补齐流程id
        insertMiddleTable(flow_id, flowStageList, stageActionList);

        trans(Arrays.asList(vo));

        return vo;
    }

    private void  insertMiddleTable(Long flow_id, List<Map<String, Object>> flowStageList, List<Map<String, Object>> stageActionList) {
        if (flowStageList.size() > 0) {
            for (Map<String, Object> map : flowStageList) {
                map.put("oppflow_id", flow_id);
                map.put("tenant_id", new Long(InvocationInfoProxy.getTenantid()));
            }
            dao.saveSql(OppflowVO.class, "batchInsertFlowStage", flowStageList);
        }

        if (stageActionList.size() > 0) {
            for (Map<String, Object> map : stageActionList) {
                map.put("oppflow_id", flow_id);
                map.put("tenant_id", new Long(InvocationInfoProxy.getTenantid()));
            }
            dao.saveSql(OppflowVO.class, "batchInsertStageAction", stageActionList);
        }
    }

    public OppflowVO getOppflowVOById(Long id) {
        OppflowVO vo = super.getVOById(OppflowVO.class, id);
        trans(Arrays.asList(vo));
        return vo;
    }

    public OppflowVO updateVO(OppflowVO vo, List<Map<String, Object>> flowStageList, List<Map<String, Object>> stageActionList) {

        vo = super.updateVO(vo);
        Map<String, Object> deleteParam = new HashMap<>();
        deleteParam.put("id", vo.getId());
        deleteParam.put("tenant_id", new Long(InvocationInfoProxy.getTenantid()));
        //这两张中间表的修改采用的是先删除后修改的方法 保证数据的一致性

        //清除中间表该流程对应的数据
        dao.delete(OppflowVO.class,"deleteFlowStage", deleteParam);
        dao.delete(OppflowVO.class,"deleteStageAction", deleteParam);

        Long flow_id = vo.getId();
        //待流程插入完成后，向List中的每条数据中补齐流程id
        insertMiddleTable(flow_id, flowStageList, stageActionList);
        //trans(Arrays.asList(vo));
        return vo;
    }

    public void batchUpdateEnableState(String[] ids, Integer enableState) {

        Map<String, Object> enableParaMap = new HashMap<String, Object>();
        enableParaMap.put("ids", ids);
        enableParaMap.put("enableState", enableState);
        enableParaMap.put("enableUserId", new Long(InvocationInfoProxy.getParameter("id")));
        enableParaMap.put("enableTime", new Date());

        dao.updateSql(OppflowVO.class, "batchUpdateEnableState", enableParaMap);

    }

    private void trans(List<OppflowVO> voList) {

        if (voList != null && voList.size() > 0) {

            List<FieldRelation<OppflowVO>> relations = new ArrayList<FieldRelation<OppflowVO>>();
            relations.add(new RefFieldRelation<OppflowVO>(OppflowVO.class, "flowState", new String[]{"flowStateName"}, baseDocDetailBizService, "selectFieldsByIds"));
            relations.add(new EnumFieldRelation<OppflowVO>(OppflowVO.class, "isPreseted", "isPresetedName", enumService, "whether"));
            relations.add(new EnumFieldRelation<OppflowVO>(OppflowVO.class, "enableState", "enableStateName", enumService, "enable_state"));
            relations.add(new RefFieldRelation<OppflowVO>(OppflowVO.class, "biztype", new String[]{"biztypeName"}, biztypeService, "selectFieldsByIds"));

            new FieldRelationHandler<OppflowVO>().handler(voList, relations);
        }
    }


    public int deleteByID( String id) {
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        param.put("tenant_id", new Long(InvocationInfoProxy.getTenantid()));
        //清除中间表该流程对应的数据
        dao.delete(OppflowVO.class,"deleteFlowStage", param);
        dao.delete(OppflowVO.class,"deleteStageAction", param);
        String[] ids = new String[]{id};
        return dao.batchDelete(OppflowVO.class, ids);
    }

    public Map<String, Object> getDetail(Long id) {
        Map<String, Object> returnMap = new HashMap<>();
        OppflowVO flowVO = super.getVOById(OppflowVO.class, id);
        returnMap.put("flowData", flowVO);

        List<Map<String, Object>> stageList = new ArrayList<>();
        returnMap.put("stageData", stageList);

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("oppflow_id", id);
        List<Map<String, Object>> flowStageList = dao.selectList(OppflowVO.class, "getFlowStageList", paramMap);

        if (flowStageList.size() > 0) {
            for (Map<String, Object> map : flowStageList) {
                Map<String, Object> stageMap = new HashMap<>();
                stageMap.put("key", map.get("oppstage_id"));
                OppstageVO stageVO = stageService.getVOById(OppstageVO.class, new Long(map.get("oppstage_id").toString()));
                stageMap.put("title", stageVO.getName());
                if (map.get("win_probability") != null) {
                    stageMap.put("winProbability", map.get("win_probability"));
                }
                /*if(map.get("sort") != 0){
                    stageMap.put("sort", map.get("sort"));
				}*/
                stageList.add(stageMap);
            }

            List<Map<String, Object>> stageActionList = dao.selectList(OppflowVO.class, "getStageActionList", paramMap);

            if (stageActionList.size() > 0) {
                for (Map<String, Object> stageMap : stageList) {
                    Long oppstage_id = new Long(stageMap.get("key").toString());
                    List<Map<String, Object>> dimList = new ArrayList<>();
                    Set<String> dimset = new HashSet<>();
                    for (Map<String, Object> map : stageActionList) {
                        if (oppstage_id.equals(new Long(map.get("oppstage_id").toString())) && !dimset.contains(map.get("oppdim_id").toString())) {
                            Map<String, Object> dimMap = new HashMap<>();
                            dimMap.put("key", map.get("oppdim_id"));
                            OppdimensionVO dimVO = dimService.getVOById(OppdimensionVO.class, new Long(map.get("oppdim_id").toString()));
                            dimMap.put("title", dimVO.getName());
                            List<Map<String, Object>> actionList = new ArrayList<>();
                            for (Map<String, Object> smap : stageActionList) {
                                if (oppstage_id.equals(new Long(smap.get("oppstage_id").toString()))
                                        && new Long(map.get("oppdim_id").toString()).equals(new Long(smap.get("oppdim_id").toString()))) {
                                    Map<String, Object> actionMap = new HashMap<>();
                                    actionMap.put("key", smap.get("oppaction_id"));
                                    OppactionVO actionVO = actionService.getVOById(OppactionVO.class, new Long(smap.get("oppaction_id").toString()));
                                    actionMap.put("title", actionVO.getName());
                                    actionList.add(actionMap);
                                }
                            }
                            if (actionList.size() > 0) {
                                dimMap.put("children", actionList);
                            }
                            dimList.add(dimMap);
                            dimset.add(map.get("oppdim_id").toString());
                        }
                    }
                    if (dimList.size() > 0) {
                        stageMap.put("children", dimList);
                    }
                }
            }
        }
        return returnMap;
    }

    public List<OppflowVO> getList(Map<String, Object> searchMap) {
        if (searchMap == null) {
            searchMap = new HashMap<>();
        }
        searchMap.put("tenant_id", new Long(InvocationInfoProxy.getTenantid()));
        List<Map<String, Object>> list = dao.selectList(OppflowVO.class, "getList", searchMap);
        List<OppflowVO> returnList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            OppflowVO flowVO = (OppflowVO) list.get(i);
            returnList.add(flowVO);
        }
        trans(returnList);
        return returnList;
    }

    public int checkBiztypeRepeat(String biztype) {
        List stageList = dao.selectList(OppflowVO.class, "checkBiztypeRepeat", biztype);
        return stageList.size();
    }
}